/****************************************************************************
 * Copyright (C) 2012
 * by Dj_Skual
 *
 * This software is provided 'as-is', without any express or implied
 * warranty. In no event will the authors be held liable for any
 * damages arising from the use of this software.
 *
 * Permission is granted to anyone to use this software for any
 * purpose, including commercial applications, and to alter it and
 * redistribute it freely, subject to the following restrictions:
 *
 * 1. The origin of this software must not be misrepresented; you
 * must not claim that you wrote the original software. If you use
 * this software in a product, an acknowledgment in the product
 * documentation would be appreciated but is not required.
 *
 * 2. Altered source versions must be plainly marked as such, and
 * must not be misrepresented as being the original software.
 *
 * 3. This notice may not be removed or altered from any source
 * distribution.
 *
 * IconList.cpp
 *
 * for SaveGame Manager GX 2012
 ***************************************************************************/
#include "../Menu/Explorer.h"
#include "IconList.h"
#include "../Themes/CTheme.h"
#include "../FileOperations/fileops.h"
#include "../FileOperations/Nand.hpp"
#include "../Saves/SaveTools.h"

IconList *IconList::instance = NULL;

IconList::IconList()
	: CThread(30)
	, ExitRequested(false)
	, Running(false)
	, addingIcon(false)
	, EntrieCount(0)
	, IconCount(0)
{
	curBrowser = NULL;
	icons.clear();
	Card = NULL;
	
	fileCfg = Resources::GetImageData("icon_brows_cfg.png");
	fileDataBin = Resources::GetImageData("icon_brows_databin.png");
	fileDefault = Resources::GetImageData("icon_brows_default.png");
	fileExe = Resources::GetImageData("icon_brows_exe.png");
	fileFolder = Resources::GetImageData("icon_brows_folder.png");
	fileFont = Resources::GetImageData("icon_brows_font.png");
	fileImg = Resources::GetImageData("icon_brows_img.png");
	fileLang = Resources::GetImageData("icon_brows_lang.png");
	fileMii = Resources::GetImageData("icon_brows_mii.png");
	fileGC = Resources::GetImageData("icon_brows_gc.png");
	fileSound = Resources::GetImageData("icon_brows_sound.png");
	fileTheme = Resources::GetImageData("icon_brows_theme.png");
	fileTxt = Resources::GetImageData("icon_brows_txt.png");
	fileXml = Resources::GetImageData("icon_brows_xml.png");
}

IconList::~IconList()
{
	ExitRequested = true;
	shutdownThread();
	while(getThread() != LWP_THREAD_NULL)
		usleep(100);
	
	ClearList();
	
	Resources::Remove(fileCfg);
	Resources::Remove(fileDataBin);
	Resources::Remove(fileDefault);
	Resources::Remove(fileExe);
	Resources::Remove(fileFolder);
	Resources::Remove(fileFont);
	Resources::Remove(fileImg);
	Resources::Remove(fileLang);
	Resources::Remove(fileMii);
	Resources::Remove(fileGC);
	Resources::Remove(fileSound);
	Resources::Remove(fileTheme);
	Resources::Remove(fileTxt);
	Resources::Remove(fileXml);
}

void IconList::ClearList()
{
	Running = false;
	EntrieCount = 0;
	IconCount = 0;
	Card = NULL;
	
	for(int i = 0; i < (int)icons.size(); ++i)
		delete icons[i];
	icons.clear();
}

GuiSaveIcon * IconList::GetSaveIcon()
{	
	std::string savepath = "";
	u64 tid = 0;
	ByteArray buffer;
	
	if(Settings.LoadedBrowser == SAVE_BROWSER)
	{
		tid = curBrowser->GetSaveTid(IconCount);
		savepath = fmt("/title/%08x/%08x/data/banner.bin", TITLE_UPPER(tid), TITLE_LOWER(tid));
		Nand::LoadFile(savepath, buffer);
	}
	else
	{
		if(Settings.LoadedBrowser == SDUSB_BROWSER)
		{
			savepath = curBrowser->GetCurrentPath();
			savepath += "/";
			savepath += curBrowser->GetItemName(IconCount);
			savepath += "/banner.bin";
		}
		else
		{
			tid = curBrowser->GetSaveTid(IconCount);
			savepath = curBrowser->GetCurrentPath();
			savepath += fmt("/title/%08x/%08x/data/banner.bin", TITLE_UPPER(tid), TITLE_LOWER(tid));
		}
		
		LoadFileToMem(savepath, buffer);
	}
	
	return (new GuiSaveIcon(buffer));
}

GuiGCIcon * IconList::GetGCIcon()
{
	if(!Card)
	{
		if(!curBrowser->GetCurrentPath().compare("gca"))
			Card = DeviceHandler::Instance()->GetGCAHandle();
		else
			Card = DeviceHandler::Instance()->GetGCBHandle();
	}
	
	GuiGCIcon * Icon = NULL;
	
	if(Card)
		Icon = Card->GetIcon(curBrowser->GetGCFilename(IconCount), 0x30, 0x30);
	
	if(!Icon)
		Icon = (GuiGCIcon*) new GuiImage(fileGC);
	
	return Icon;
}

GuiImage * IconList::GetIconImg()
{
	if ((Settings.LoadedBrowser == SAVE_BROWSER) ||
		(Settings.LoadedBrowser == ESAVE_BROWSER))
		return (GetSaveIcon());
	
	if(Settings.LoadedBrowser == GC_BROWSER)
		return (GetGCIcon());
	
	if(curBrowser->IsSave(IconCount))
		return (GetSaveIcon());
	
	/*if(curBrowser->IsGCSave(IconCount))
		return (GetGCIcon());*/
	
	if(curBrowser->IsDir(IconCount))
		return (new GuiImage(fileFolder));
	
	if(curBrowser->IsMii(IconCount))
		return (new GuiImage(fileMii));
	
	if(curBrowser->IsDataBin(IconCount))
		return (new GuiImage(fileDataBin));
	
	std::string fileext = wstr2str(curBrowser->GetItemDisplayName(IconCount));
	int index = fileext.find_last_of('.');
	if(index > 0)
	{
		fileext = fileext.substr(index);
		if(!fileext.compare("."))
			fileext = "";
	}
	else
		fileext = "";
	
	ToLowerCase(fileext);
	
	if(!fileext.empty())
	{
		if(!fileext.compare(".cfg"))
		{
			return (new GuiImage(fileCfg));
		}
		else if (!CompareHomebrew(fileext.c_str()))
		{
			return (new GuiImage(fileExe));
		}
		else if(!CompareFont(fileext.c_str()))
		{
			return (new GuiImage(fileFont));
		}
		else if (!CompareImage(fileext.c_str()))
		{
			return (new GuiImage(fileImg));
		}
		else if(!CompareLanguageFiles(fileext.c_str()))
		{
			return (new GuiImage(fileLang));
		}
		else if(!CompareAudio(fileext.c_str()))
		{
			return (new GuiImage(fileSound));
		}
		else if(!CompareThemeFiles(fileext.c_str()))
		{
			return (new GuiImage(fileTheme));
		}
		else if(!fileext.compare(".log") ||
				!fileext.compare(".txt"))
		{
			return (new GuiImage(fileTxt));
		}
		else if(!fileext.compare(".xml"))
		{
			return (new GuiImage(fileXml));
		}
	}

	return (new GuiImage(fileDefault));
}

void IconList::AddIcon()
{
	addingIcon = true;
	
	icons.push_back(GetIconImg());
	IconCount++;
	
	addingIcon = false;
}

GuiImage * IconList::GetIcon(int index)
{
	if(index < 0 || index >= (int)icons.size())
		return NULL;
	
	return icons[index];
}

void IconList::Get(Browser * browser)
{
	Running = false;
	while(addingIcon)
		usleep(50);
	
	ClearList();
	
	curBrowser = browser;
	EntrieCount = curBrowser->GetEntrieCount();
	
	Running = true;
	resumeThread();
}

void IconList::executeThread(void)
{
	while(!ExitRequested)
	{
		if(!Running)
		{
			suspendThread();
			usleep(100);
			continue;
		}
		else
		{
			if(IconCount < EntrieCount)
				AddIcon();
			else
			{
				Running = false;
				Card = NULL;
			}
		}
	}
}
